#pragma once

#include <cv.h>
#include <highgui.h>
#include "../armed/time.h"
#include <vector>
#include "structures.h"
#include "ColorsHSV.h"

CvMat* perspective(IplImage *frame, IplImage *search, int razmer);
int find(int type, int &aX, int &aY, IplImage* search, ColorsHSV &c, int fspace, int erspace,int razmer);

const int COLUMN_DIMENSION = 5;
const int ERROR_TOLERANCE = 5;
const int RAZMER = 32;

#define DEBUG_WINDOWS 0

class Camera
{
	CvCapture* capture;
	IplImage * image;
	IplImage * search;
	MouseEvent event;

	CvMat* perspective_matrix;
	ColorsHSV colors;

	void mouse_event( int event_, int x, int y, int flags )
	{
		//printf("event: %d x: %d y: %d flags: %d \t\t r:%d g:%d b:%d\n",
		//	event_, x, y, flags, r, g, b );
	}

public:
	Time time;
	
	Camera(
		int camera_index,
		Filter & red, 
		Filter & green,
		Filter & blue,
		Filter & empty
		)
	{
		image = NULL;
		capture = cvCaptureFromCAM( camera_index );
		if ( !capture ) {
			throw " cannot access camera device ";
		}

		search = cvCreateImage( cvSize(160, 120), 8, 3 );
		image = cvQueryFrame( capture );
		perspective_matrix = perspective(image, search, RAZMER);
		colors._initialize(red, green, blue, empty);

#if DEBUG_WINDOWS == 1
		cvNamedWindow("original", CV_WINDOW_AUTOSIZE);
		cvNamedWindow("search", CV_WINDOW_AUTOSIZE);
#endif

		///printf(" + channel seq: %c%c%c%c\n", image->channelSeq[0], image->channelSeq[1], image->channelSeq[2], image->channelSeq[3]);
	}
	~Camera()
	{
		cvReleaseCapture( &capture );

#if DEBUG_WINDOWS == 1
		cvDestroyWindow("original");
		cvDestroyWindow("result");
#endif
	}

	CameraResult process(int type)
	{
		CameraResult ret;
		image = cvQueryFrame( capture );
		if( image ) {
			int rx, ry;

			cvWarpPerspective(image, search, perspective_matrix );
			cvCvtColor(search, search, CV_RGB2HSV);

			int status = find(type, ry, rx, search, colors, COLUMN_DIMENSION, ERROR_TOLERANCE, RAZMER);
			if(status == 1)
			{
				ret.x = rx;
				ret.y = ry;
				ret.status = 1;
			}

#if DEBUG_WINDOWS == 1
			cvShowImage("original", image);
			cvShowImage("search",search);
			cvWaitKey(5);
#endif
		}
		return ret;
	}


	MouseEvent get_event()
	{
		MouseEvent ret = event;
		event.triggered = false;
		return ret;
	}

	static void on_mouse( int event, int x, int y, int flags, void* param )
	{
		Camera * object = (Camera *) param;
		if (object)
			object->mouse_event(event, x, y, flags);
	}

};










